package main

import (
	"fmt"
	"reflect"
)

// IPlayer go的面向接口编程，是以一种松散的契约关系，
// 只要覆盖了接口中的方法，则为实现了接口，就可以被当作接口类型使用
type IPlayer interface {
	trainMethod()
}

type DefaultPlayer2 struct {
	name string
}

// 接口类型 IPlayer 不用写“*”号，默认接收的就是指针类型
func (d *DefaultPlayer2) sign(player IPlayer) {
	fmt.Println("默认的训练")
	player.trainMethod()
}

type FootballPlayer2 struct {
	DefaultPlayer2
}

func (f *FootballPlayer2) trainMethod() {
	fmt.Println("足球运动员的训练")
}

type BasketballPlayer2 struct {
	DefaultPlayer2
}

func (f *BasketballPlayer2) trainMethod() {
	fmt.Println("篮球运动员的训练")
}

type SwimmingPlayer2 struct {
	DefaultPlayer2
}

func (f *SwimmingPlayer2) trainMethod() {
	fmt.Println("游泳运动员的训练")
}

func main() {
	//使用接口,基本达到了多态的形式
	//一定要返回地址给指针类型，因为以接口类型的函数，直接收对象的指针数据
	var a = &FootballPlayer2{DefaultPlayer2{"A"}}
	fmt.Printf("a=%p,%s\n", a, reflect.TypeOf(a))
	a.sign(a)
	b := &BasketballPlayer2{DefaultPlayer2{"B"}}
	b.sign(b)
	s := &SwimmingPlayer2{DefaultPlayer2{"C"}}
	s.sign(s)
}
